package com.client.job.utils;

import java.text.DateFormat;
import java.text.DecimalFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.*;
import java.time.format.DateTimeFormatter;
import java.time.temporal.TemporalAdjusters;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

public class DateUtil {
	public static String YYYY = "yyyy";

	public static String YYYY_MM = "yyyy-MM";

	public static String YYYY_MM_DD = "yyyy-MM-dd";

	public static String YYYYMMDDHHMMSS = "yyyyMMddHHmmss";

	public static String YYYYMMDD = "yyyyMMdd";

	public static String YYYYMM = "yyyyMM";

	public static String YYYYMMDD000000 = "yyyyMMdd000000";

	public static String YYYY_MM_DD_HH_MM_SS = "yyyy-MM-dd HH:mm:ss";

	public static final String parseDateToStr(final String format, final Date date) {
		return new SimpleDateFormat(format).format(date);
	}

	/**
	 * 字符串转时间
	 * 
	 * @param time        时间字符串
	 * @param datePatterm 时间格式
	 * @return
	 */
	public static Date StringToDate(String time, String datePatterm) {
		SimpleDateFormat df = new SimpleDateFormat(datePatterm);
		try {
			return df.parse(time);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;

	}

	/**
	 * 获取到当前日期
	 * 
	 * @param format 日期格式
	 * @return
	 */
	public static String nowDate(String format) {
		Calendar calendar = Calendar.getInstance();
		SimpleDateFormat dateFormat = new SimpleDateFormat(format);
		return dateFormat.format(calendar.getTime());
	}

	/**
	 * 获取到几个小后的时间
	 * 
	 * @param hour   小时
	 * @param format 时间格式
	 * @return
	 */
	public static String afterHours(Integer hour, String format) {
		Calendar calendar = Calendar.getInstance();
		calendar.add(Calendar.HOUR, hour);
		SimpleDateFormat dateFormat = new SimpleDateFormat(format);
		return dateFormat.format(calendar.getTime());
	}

	/**
	 * 获取到下一个整小时
	 * 
	 * @return
	 */
	public static Date getNextHour() {
		Calendar ca = Calendar.getInstance();
		ca.add(Calendar.HOUR_OF_DAY, 1);
		ca.set(Calendar.MINUTE, 0);
		ca.set(Calendar.SECOND, 0);
		ca.set(Calendar.MILLISECOND, 0);
		return ca.getTime();
	}

	/**
	 * 在某一个时间后添加N小时和N分钟
	 * 
	 * @param time
	 * @param hours
	 * @param mins
	 * @return
	 */
	public static Date addHoursAndMins(Date time, Integer hours, Integer mins) {
		if (time == null) {
			time = new Date();
		}
		Calendar ca = Calendar.getInstance();
		ca.setTime(time);
		ca.add(Calendar.HOUR_OF_DAY, hours == null ? 0 : hours);
		ca.add(Calendar.MINUTE, mins == null ? 0 : mins);
		return ca.getTime();
	}

	/**
	 * 在某一个时间后添加N小时和N分钟
	 * 
	 * @param time
	 * @param hours
	 * @param mins
	 * @return
	 */
	public static Date addHoursAndMins(Date time, Double hoursAndMinss) {
		Integer hours = 0;
		Integer mins = 0;
		if (hoursAndMinss.toString().contains(".")) {
			hours = Integer.valueOf(hoursAndMinss.toString().split("\\.")[0]);
			mins = Integer.valueOf(hoursAndMinss.toString().split("\\.")[1]) * 6;
		} else {
			hours = Integer.valueOf(hoursAndMinss.toString());
		}

		if (time == null) {
			time = new Date();
		}
		Calendar ca = Calendar.getInstance();
		ca.setTime(time);
		ca.add(Calendar.HOUR_OF_DAY, hours);
		ca.add(Calendar.MINUTE, mins);
		return ca.getTime();
	}

	/**
	 * 计算2哥时间的小时差，精确到小数点1位
	 * 
	 * @return
	 */
	public static Double getPoorTimeHours(Date d1, Date d2) {
		Long senconds = d2.getTime() - d1.getTime();
		return Double.valueOf(new DecimalFormat("######0.0").format(senconds / (3600 * 1000L)));
	}

	/**
	 * 设置大多少点的时间
	 * 
	 * @return
	 */
	public static Date setTimeByHour(Date time, Integer hour) {
		if (time == null) {
			time = new Date();
		}
		Calendar ca = Calendar.getInstance();
		ca.setTime(time);
		ca.set(Calendar.HOUR_OF_DAY, hour);
		return ca.getTime();
	}

	/**
	 * 设置大多少点的时间
	 * 
	 * @return
	 */
	public static Date setTimeByHours(Date time, Integer hour, Integer minInteger) {
		if (time == null) {
			time = new Date();
		}
		Calendar ca = Calendar.getInstance();
		ca.setTime(time);
		ca.set(Calendar.HOUR_OF_DAY, hour);
		ca.set(Calendar.MINUTE, minInteger);
		return ca.getTime();
	}

	/**
	 * 设置加+天的方式
	 * 
	 * @param time
	 * @param days
	 * @return
	 */
	public static Date addTimeDays(Date time, Integer days) {
		if (time == null) {
			time = new Date();
		}
		Calendar ca = Calendar.getInstance();
		ca.setTime(time);
		ca.add(Calendar.DATE, days);
		return ca.getTime();
	}

	public static Date addTimeSeconds(Date time, long seconds) {
		if (time == null) {
			time = new Date();
		}
		Calendar ca = Calendar.getInstance();
		ca.setTime(time);
		ca.add(Calendar.SECOND, (int) seconds);
		return ca.getTime();
	}
	
	

	/**
	 * 获取2个时间的时间差，返回毫秒
	 * 
	 * @param endDate
	 * @param nowDate
	 * @return
	 */
	public static Long getDatePoorTime(Date startTime, Date endTime) {
		if (startTime == null) {
			startTime = getNowDate();
		}
		return endTime.getTime() - startTime.getTime();
	}

	/**
	 * 获取当前Date型日期
	 * 
	 * @return Date() 当前日期
	 */
	public static Date getNowDate() {
		return new Date();
	}

	/**
	 * 计算2个时间差，如果结束时间没有就选择当前时间
	 * 
	 * @param beginTime 开始时间
	 * @param endTime   结束时间
	 * @return
	 */
	public static final Long dayDark(String beginTime, String endTime, String timeParam) {
		DateTimeFormatter formatter = DateTimeFormatter.ofPattern(timeParam);
		LocalDate from = LocalDate.parse(beginTime, formatter);

		if (endTime == null) {
			return LocalDate.now().toEpochDay() - from.toEpochDay();
		} else {
			LocalDate end = LocalDate.parse(endTime, formatter);
			return end.toEpochDay() - from.toEpochDay();
		}
	}

	/**
	 * 计算时间段的同比（比如开始时间为本周一，结束时间为本周三，间隔-7天，则获取到上周一到上周三的时间端）
	 * 
	 * @param beginDate
	 * @param endDate
	 * @param gapDays
	 * @return
	 */
	public static final List<String> dayChain(Date beginDate, Date endDate, Integer gapDays) {
		//
		LocalDate beginTime = beginDate.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
		LocalDate endTime = endDate.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
		long gapTimes = endTime.toEpochDay() - beginTime.toEpochDay();
		// 上个同时间段
		LocalDate lastBeginTime = beginTime.plusDays(gapDays);
		LocalDate lastEndTime = lastBeginTime.plusDays(gapTimes);
		DateTimeFormatter formatter = DateTimeFormatter.ofPattern(YYYYMMDD + "000000");
		List<String> list = new ArrayList<>();
		list.add(lastBeginTime.format(formatter));
		list.add(lastEndTime.format(formatter));
		return list;
	}

	/**
	 * 获取到时间的本周一日期，如果为空则默认去当前时间
	 * 
	 * @param time
	 * @return
	 */
	public static final Date getMonday(Date time) {
		LocalDate beginTime = time == null ? LocalDate.now()
				: time.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
		LocalDate monday = beginTime.with(TemporalAdjusters.previousOrSame(DayOfWeek.SUNDAY));
		ZoneId zone = ZoneId.systemDefault();
		Instant instant = monday.atStartOfDay().atZone(zone).toInstant();
		return Date.from(instant);
	}

	/**
	 * 获取到时间间隔的时间日期
	 * 
	 * @param date
	 * @param gapDays
	 * @return
	 */
	public static final Date getDayGaps(Date date, int gapDays) {
		LocalDate localDate = date.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
		localDate = localDate.plusDays(gapDays);
		ZoneId zone = ZoneId.systemDefault();
		Instant instant = localDate.atStartOfDay().atZone(zone).toInstant();
		return Date.from(instant);
	}

	/**
	 * 获取到时间间隔的时间日期(整时间小时)
	 * 
	 * @param date
	 * @param gapHours
	 * @return
	 */
	public static final Date getHourGaps(Date date, int gapHours) {
		Calendar ca = Calendar.getInstance();
		ca.setTime(date);
		ca.add(Calendar.HOUR, gapHours);
		return ca.getTime();
	}

	/**
	 * 获取到今天凌晨时间
	 *
	 * @return
	 */
	public static Date getLinChen(Date date) {
		if (date == null) {
			date = new Date();
		}
		LocalDateTime localDateTime = LocalDateTime.ofInstant(Instant.ofEpochMilli(date.getTime()),
				ZoneId.systemDefault());
		LocalDateTime day = localDateTime.with(LocalTime.MIN);
		Date endTime = Date.from(day.atZone(ZoneId.systemDefault()).toInstant());
		return endTime;
	}

	/**
	 * 获取到今天凌晨时间
	 *
	 * @return
	 */
	public static Date getNextDayLinChen(Date date) {
		if (date == null) {
			date = new Date();
		}
		LocalDateTime localDateTime = LocalDateTime.ofInstant(Instant.ofEpochMilli(date.getTime()),
				ZoneId.systemDefault());
		LocalDateTime day = localDateTime.with(LocalTime.MIN);
		Date endTime = Date.from(day.atZone(ZoneId.systemDefault()).toInstant());
		return addTimeDays(endTime, 1);
	}

	/**
	 * 获取夜间12时间
	 * 
	 * @param date
	 * @return
	 */
	public static Date getYj(Date date) {
		if (date == null) {
			date = new Date();
		}
		return setTimeByHours(date, 23, 00);
	}

	/**
	 * 格式化时间字符串
	 * 
	 * @param time
	 * @param datePatterm
	 * @return
	 */
	public static String getTimeStr(String time, String datePatterm) {
		DateFormat format = new SimpleDateFormat(datePatterm);
		Date dateString = null;
		try {
			dateString = format.parse(time);
		} catch (ParseException e) {
			e.printStackTrace();
		}

		return format.format(dateString);
	}

	/**
	 * 获取到2个月份间隔的月份，包括本身
	 * 
	 * @param date1
	 * @param date2
	 * @param datePatterm
	 * @return
	 */
	public static List<String> getJgMon(String startDateStr, String endDateStr, String datePatterm) {
		try {
			Date startDate = new SimpleDateFormat(datePatterm).parse(startDateStr);
			Date endDate = new SimpleDateFormat(datePatterm).parse(endDateStr);

			Calendar calendar = Calendar.getInstance();
			calendar.setTime(startDate);
			// 获取开始年份和开始月份
			int startYear = calendar.get(Calendar.YEAR);
			int startMonth = calendar.get(Calendar.MONTH);
			// 获取结束年份和结束月份
			calendar.setTime(endDate);
			int endYear = calendar.get(Calendar.YEAR);
			int endMonth = calendar.get(Calendar.MONTH);
			//
			List<String> list = new ArrayList<String>();
			for (int i = startYear; i <= endYear; i++) {
				String date = "";
				if (startYear == endYear) {
					for (int j = startMonth; j <= endMonth; j++) {
						if (j < 9) {
							date = i + "0" + (j + 1);
						} else {
							date = i + "" + (j + 1);
						}
						list.add(date);
					}

				} else {
					if (i == startYear) {
						for (int j = startMonth; j < 12; j++) {
							if (j < 9) {
								date = i + "0" + (j + 1);
							} else {
								date = i + "" + (j + 1);
							}
							list.add(date);
						}
					} else if (i == endYear) {
						for (int j = 0; j <= endMonth; j++) {
							if (j < 9) {
								date = i + "0" + (j + 1);
							} else {
								date = i + "" + (j + 1);
							}
							list.add(date);
						}
					} else {
						for (int j = 0; j < 12; j++) {
							if (j < 9) {
								date = i + "0" + (j + 1);
							} else {
								date = i + "" + (j + 1);
							}
							list.add(date);
						}
					}

				}

			}

			List<String> resList = new ArrayList<>();
			for (String str : list) {
				resList.add(DateUtil.parseDateToStr(datePatterm, StringToDate(str, YYYYMM)));
			}
			return resList;
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}

	/**
	 * 获取到2个日期的时间间隔
	 * 
	 * @param beginStr
	 * @param endStr
	 * @param datePatterm
	 * @return
	 */
	public static List<String> getMiddleDate(String beginStr, String endStr, String datePatterm) {
		DateTimeFormatter formatter = DateTimeFormatter.ofPattern(datePatterm);
		LocalDate begin = LocalDate.parse(beginStr, formatter);
		LocalDate end = LocalDate.parse(endStr, formatter);

		List<String> localDateList = new ArrayList<>();
		long length = end.toEpochDay() - begin.toEpochDay();
		for (long i = length; i >= 0; i--) {
			localDateList.add(end.minusDays(i).format(formatter));
		}
		return localDateList;
	}

	/**
	 * 获取到2个日期的时间间隔
	 * 
	 * @param beginStr
	 * @param endStr
	 * @param datePatterm
	 * @return
	 */
	public static List<String> getMiddleDate(Date beginDate, Date endDate, String datePatterm) {
		DateTimeFormatter formatter = DateTimeFormatter.ofPattern(datePatterm);
		LocalDate begin = beginDate.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
		LocalDate end = endDate.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();

		List<String> localDateList = new ArrayList<>();
		long length = end.toEpochDay() - begin.toEpochDay();
		for (long i = length; i >= 0; i--) {
			localDateList.add(end.minusDays(i).format(formatter));
		}
		return localDateList;
	}

	

	/**
	 * 获取到下一个月的当前时间
	 * 
	 * @param nowDate
	 * @param datePatterm
	 * @return
	 */
	public static String getNextMonth(Date nowDate, String datePatterm) {
		LocalDate date = nowDate.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
		date = date.minusMonths(-1);
		return date.format(DateTimeFormatter.ofPattern(datePatterm));
	}

	/**
	 * 获取多少秒后的时间
	 * 
	 * @param date
	 * @param seconds
	 * @return
	 */
	public static String getDateStrToSenconds(Date date, Long seconds) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		calendar.add(Calendar.SECOND, Integer.valueOf(seconds.toString()));
		Date newDate = calendar.getTime();
		return parseDateToStr(YYYY_MM_DD_HH_MM_SS, newDate);
	}

	/**
	 * 获取多少秒后的时间
	 * 
	 * @param date
	 * @param seconds
	 * @return
	 */
	public static Date getDateToSenconds(Date date, Long seconds) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(date);
		calendar.add(Calendar.SECOND, Integer.valueOf(seconds.toString()));
		return calendar.getTime();
	}

	/**
	 * 时间比较，c2时间是否在c1之后
	 * 
	 * @param c1
	 * @param c2
	 * @return
	 */
	public static boolean compareTime(Date c1, Date c2) {
		return c2.getTime() >= c1.getTime();
	}

}
